/**
 * 缓存相关工具函数
 * 提供函数结果缓存、记忆化等性能优化功能
 */

/**
 * 函数结果缓存/记忆化
 * @template T - 函数类型
 * @param {T} func - 要缓存结果的函数
 * @param {object} [options] - 配置选项
 * @param {(...args: Parameters<T>) => string} [options.keyGenerator] - 用于生成缓存键的函数
 * @param {Map<string, ReturnType<T>>} [options.cache] - 自定义缓存对象
 * @returns {T} 包装后的函数
 * @example
 * const expensiveOperation = memoize((a, b) => {
 *   console.log('Computing...');
 *   return a + b;
 * });
 * 
 * console.log(expensiveOperation(2, 3)); // 计算并返回5
 * console.log(expensiveOperation(2, 3)); // 直接从缓存返回5，不打印'Computing...'
 */
export function memoize<T extends (...args: any[]) => any>(
  func: T,
  options: {
    keyGenerator?: (...args: Parameters<T>) => string;
    cache?: Map<string, ReturnType<T>>;
  } = {}
): T {
  const cache = options.cache || new Map<string, ReturnType<T>>();
  const keyGenerator = options.keyGenerator || ((...args: any[]) => {
    // 简单的键生成策略：将参数JSON序列化
    try {
      return JSON.stringify(args);
    } catch (error) {
      // 如果无法序列化，生成一个基于参数数量和类型的键
      return args.map((arg, index) => `${index}:${typeof arg}`).join(',');
    }
  });

  return function (...args: Parameters<T>): ReturnType<T> {
    const key = keyGenerator(...args);
    if (cache.has(key)) {
      return cache.get(key)!;
    }

    const result = func(...args);
    cache.set(key, result);
    return result;
  } as T;
}